/*
* PROJECT: Happy New Year
* VERSION: 1.0
* AUTHOR: Mattias Thell
* URL: http://www.mattiasthell.com
*
* */

#include "ActorManager.hpp"

#include "Foreach.h"

namespace hny {

	ActorManager* ActorManager::mInstance = 0;

	ActorManager::ActorManager()
		:mNextId(ActorIdStart)
	{
		mActors.reserve(ActorVectorDefaultSize);
	}

	ActorManager::~ActorManager()
	{
	}

	ActorManager* ActorManager::GetInstance() {
		
		if(mInstance == 0)
			mInstance = new ActorManager();

		return mInstance;
	}

	void ActorManager::Destroy() {
		if(mInstance != 0) {
			delete mInstance;
			mInstance = 0;
		}
	}

	void ActorManager::Update(float dt)
	{
		////////////////////////
		// Insert new actors
		foreach(ActorType a, mNewActors) {
			mActors.push_back(a);
		}
		mNewActors.clear();

		/////////////////////////
		// Update all actors
		foreach(ActorType a, mActors) {
			if(a->IsAlive())
				a->Update(dt);
		}

		CleanUp();
	}

	void ActorManager::CleanUp() 
	{
		mActors.erase(std::remove_if(mActors.begin(), mActors.end(), NeedsRemoval()), mActors.end());
	}

	void ActorManager::AddActor(ActorType actor) 
	{
		// We have to insert new actors in a separate vector since
		// entities might create new actors themselves (while being updated). 
		// If they would be directly inserted into mActors, it could 
		// invalidate the iterator.
		mNewActors.push_back(actor);
	}

	void ActorManager::FreeActor(int index)
	{
	}

	const ActorVector& ActorManager::GetActors() { return mActors; }

	void ActorManager::EraseAll()
	{
		mActors.clear();
	}

	unsigned int ActorManager::GetNewId() {
		return mNextId++;
	}
}